home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / visulztn / saoimage / saoimage.lha / readint.c < prev    next >
C/C++ Source or Header  |  1990-04-20  |  7KB  |  265 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    readint.c (Read Integer)
  6.  * Purpose:    Scale fixed point image data to fit in a short (int*2) buffer
  7.  * Subroutine:    scale_data_u1()            returns: void
  8.  * Subroutine:    scale_data_i2()            returns: void
  9.  * Subroutine:    scale_data_u2()            returns: void
  10.  * Subroutine:    scale_data_i4()            returns: void
  11.  * Xlib calls:    none
  12.  * Copyright:    1988 Smithsonian Astrophysical Observatory
  13.  *        You may do anything you like with this file except remove
  14.  *        this copyright.  The Smithsonian Astrophysical Observatory
  15.  *        makes no representations about the suitability of this
  16.  *        software for any purpose.  It is provided "as is" without
  17.  *        express or implied warranty.
  18.  * Modified:    {0} Michael VanHilst    initial version         31 October 1988
  19.  *        {1} Juha Salo (kali@altair.utu.fi) scale_data_u1 17 Oct 1989
  20.  *              {2} Stephan Jansen scale_data_i4 (overflow fix) 8-Dec 1989
  21.  *                         jansen%madraf.decnet@vms.macc.wisc,edu
  22.  *        {n} <who> -- <does what> -- <when>
  23.  */
  24.  
  25. #include <sys/types.h>        /* needed for ntohl (net to host long) */
  26. #ifndef VMS
  27. #include <netinet/in.h>        /* needed for ntohl (net to host long) */
  28. #endif
  29. #include "hfiles/scale.h"    /* define SCALEWIDTH, etc. */
  30. #include "hfiles/image.h"    /* image struct */
  31.  
  32. /*
  33.  * Subroutine:    scale_data_u1
  34.  * Purpose:    Read an 8-bit array into a 16-bit buffer
  35.  * Method:    Copy from end so byte data may occupy beginning of same buf
  36.  */
  37. void scale_data_u1 ( image, imgbuf, databuf, vals )
  38.      struct imageRec *image;
  39.      register short *imgbuf;
  40.      register unsigned char *databuf;
  41.      int vals;
  42. {
  43.   databuf += (vals - 1);
  44.   imgbuf += (vals - 1);
  45.   /* and pad the picture */
  46.   while( vals-- > 0 )
  47.     *imgbuf-- = (short)*databuf--;
  48.   image->fiscaled = 0;
  49.   image->fibias = 0.0;
  50.   image->fiscale = 1.0;
  51. }
  52.  
  53. /*
  54.  * Subroutine:    scale_data_i2
  55.  * Purpose:    Scale 16-bit signed short data into the (short) img array
  56.  * Method:    Data is assumed to be already in the buffer.  Only byte-swap
  57.  *        might be needed.
  58.  */
  59. void scale_data_i2 ( image, imgbuf, databuf, vals )
  60.      struct imageRec *image;
  61.      short *imgbuf;
  62.      short *databuf;
  63.      int vals;
  64. {
  65.   static void byte_swap();
  66.  
  67.   /* do byte swap if called for */
  68.   if( image->byte_swap )
  69.     byte_swap((char *)databuf, (char *)imgbuf, vals * sizeof(short));
  70.   image->fiscaled = 0;
  71.   image->fibias = 0.0;
  72.   image->fiscale = 1.0;
  73. }
  74.  
  75. /*
  76.  * Subroutine:    scale_data_u2
  77.  * Purpose:    Scale 16 bit unsigned short data into the (short) img array
  78.  */
  79. void scale_data_u2 ( image, imgbuf, databuf, vals )
  80.      struct imageRec *image;
  81.      register short *imgbuf;
  82.      register unsigned short *databuf;
  83.      int vals;
  84. {
  85.   register unsigned short *dataend;
  86.   register int bias;
  87.   static void byte_swap();
  88.  
  89.   bias = -SCALEOFF;
  90.   /* do byte swap if called for */
  91.   if( image->byte_swap )
  92.     byte_swap((char *)databuf, (char *)imgbuf, vals * sizeof(short));
  93.   /* start from back end since data may occupy beginning of buf */
  94.   dataend = databuf + vals;
  95.   do {
  96.     *imgbuf++ = (short)((int)*databuf + bias);
  97.   } while( ++databuf < dataend );
  98.   image->fiscaled = 1;
  99.   image->fibias = -(double)bias;
  100.   image->fiscale = 1.0;
  101. }
  102.  
  103. /*
  104.  * Subroutine:    scale_data_i4
  105.  * Purpose:    Scale 32 bit integer data into the (short) img array
  106.  */
  107. void scale_data_i4 ( image, imgbuf, databuf, vals, verbose )
  108.      struct imageRec *image;
  109.      short *imgbuf;
  110.      long *databuf;
  111.      int vals;
  112.      int verbose;        /* whether to print explanatory messages */
  113. {
  114.   register long *lbuf, *lbufend;
  115.   int datamin, datamax;
  116.  
  117.   {
  118.     register int lmin, lmax;
  119.     lbuf = databuf;
  120.     lbufend = lbuf + vals;
  121.     /* find the min and the max (byteswap if needed) */
  122.     if( image->byte_swap ) {
  123.       *lbuf = (long)ntohl((unsigned long)*lbuf);
  124.       lmin = lmax = *lbuf;
  125.       /* skip the first val since we just used it */
  126.       while( ++lbuf < lbufend ) {
  127.     *lbuf = (long)ntohl((unsigned long)*lbuf);
  128.     if( *lbuf < lmin )
  129.       lmin = *lbuf;
  130.     else if( *lbuf > lmax )
  131.       lmax = *lbuf;
  132.       }
  133.     } else {
  134.       lmin = lmax = *lbuf;
  135.       while( ++lbuf < lbufend ) {
  136.     if( *lbuf < lmin )
  137.       lmin = *lbuf;
  138.     else if( *lbuf > lmax )
  139.       lmax = *lbuf;
  140.       }
  141.     }
  142.     datamin = lmin;
  143.     datamax = lmax;
  144.   }
  145.   /* make announcement if requested */
  146.   if( verbose ) {
  147.     (void)printf("min and max as read: %d, %d\n", datamin, datamax);
  148.     if( image->fimin < image->fimax ) {
  149.       (void)printf("using given limits: %d, %d\n",
  150.            (int)image->fimin, (int)image->fimax);
  151.     }
  152.   }
  153.   /* apply preset limits if given */
  154.   if( image->fimin < image->fimax ) {
  155.     if( image->fimin < 0.0 )
  156.       datamin = (int)(image->fimin - 0.5);
  157.     else
  158.       datamin = (int)(image->fimin + 0.5);
  159.     if( image->fimax < 0.0 )
  160.       datamax = (int)(image->fimax - 0.5);
  161.     else
  162.       datamax = (int)(image->fimax + 0.5);
  163.   }  
  164.   {
  165.     register short *sbuf;
  166.     register long bias;
  167.     double scale;
  168.     register int smin, smax;
  169.  
  170.     /*
  171.      *  I inserted a number of (float) conversions to stop the problem
  172.      *  with overflow.
  173.      *  Stephan Jansen
  174.      */
  175.  
  176.     smin = SCALEMIN;
  177.     smax = SCALEMAX;
  178.     /* reset buf pointer for another pass through lbuf */
  179.     lbuf = databuf;
  180.     sbuf = imgbuf;
  181.     if( ((double)datamax - (double)datamin) <= (double)SCALEWIDTH ) {
  182.       /* if a simple offset suffices */
  183.       register long ltemp;
  184.       if( (datamin >= SCALEMIN) && (datamax <= SCALEMAX) ) {
  185.     /* if possible to truncate to short without bias, do so. */
  186.     bias = 0;
  187.     image->fiscaled = 0;
  188.     image->fibias = 0.0;
  189.       } else {
  190.     /* offset by average to center within range */
  191.     bias = -((datamin + datamax) / 2);
  192.     image->fiscaled = 1;
  193.     image->fibias = (double)(-bias);
  194.       }
  195.       image->fiscale = 1.0;
  196.       do {
  197.     ltemp = *lbuf + bias;
  198.     if( ltemp < smin ) {
  199.       *sbuf++ = smin;
  200.     } else if( ltemp > smax ) {
  201.       *sbuf++ = smax;
  202.     } else
  203.       *sbuf++ = (short)ltemp;
  204.       } while( ++lbuf < lbufend );
  205.     } else {
  206.       /* full-up scaling required. (+/- (tmax-tmin)/2) */
  207.       double dtemp, dmin, dmax, dbias;
  208.       /* offset values to be zero centered */
  209.       dbias = -(((double)datamin + (double)datamax) * 0.5);
  210.       /* get the scale factor (no divide by zero gets past prior test) */
  211.       scale = (double)SCALEWIDTH / ((double)datamax - (double)datamin);
  212.       /* use min and max to mark out limits as float values */
  213.       dmin = (double)SCALEMIN;
  214.       dmax = (double)SCALEMAX;
  215.       /* scale the picture */
  216.       do {
  217.     dtemp = ((double)(*lbuf) + dbias) * scale;
  218.     if( dtemp < 0.0 ) {
  219.       dtemp -= 0.5;
  220.       if( dtemp < dmin )
  221.         *sbuf++ = smin;
  222.       else
  223.         *sbuf++ = (short)dtemp;
  224.     } else {
  225.       dtemp += 0.5;
  226.       if( dtemp > dmax )
  227.         *sbuf++ = smax;
  228.       else
  229.         *sbuf++ = (short)dtemp;
  230.     }
  231.       } while( ++lbuf < lbufend );
  232.       image->fiscaled = 1;
  233.       image->fibias = -dbias;
  234.       image->fiscale = 1.0 / scale;
  235.     }
  236.   }
  237. }
  238.  
  239. /*
  240.  * Subroutine:    byte_swap
  241.  * Purpose:    Equivalent of UNIX swab, but guaranteed to work in place
  242.  *        and usable under VMS
  243.  */
  244. static void byte_swap( inbuf, outbuf, nbytes )
  245.      char *inbuf;
  246.      char *outbuf;
  247.      int nbytes;
  248. {
  249.   register char *from, *to, *last_byte;
  250.   register unsigned temp;
  251.  
  252.   from = inbuf;
  253.   to = outbuf;
  254.   last_byte = from + nbytes;
  255.   while( from < last_byte ) {
  256.     temp = *from;
  257.     ++from;
  258.     *to = *from;
  259.     ++to;
  260.     *to = temp;
  261.     ++to;
  262.     ++from;
  263.   }
  264. }
  265.